﻿using Slex;
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Linq;
using System.IO;
using System.Reflection;
using ArithCollect;

namespace CaseMap {
    public class MudelManager {
        internal MudelManager() {
            this.bagExceptionStore = new List<BagException>();
            bags = new Dictionary<string, Assembly>();
            pages = new List<Tople<object, string, string>>();
        }
        public void ConfigXaps(params string[] xaps) {
            foreach (var item in xaps) {
                bags.Add(item, null);
            }
        }
        public void Reset() {
            bags.Clear();
            pages.Clear();
        }
        internal List<Tople<object, string, string>> pages;
        internal object GetPage(string xapname, string typename) {
            var r = default(object);
            LoadMudel(xapname, typename);
            var x = bags[xapname];
            var x3 = from item in pages where item[xapname] != null && item[xapname][typename] != null select item;
            if (x3.Count() == 0) {
                r = Activator.CreateInstance(x.GetType(string.Format("{0}.{1}", xapname, typename)));
                pages.Add(Tople.C<object, string, string>(r, typename, xapname));
            } else if (x3.Count() == 1) {
                r = x3.First().Item1;
            } else {
                pages.Remove(x3.First());//确保一个assembly中只有一个视图接口
            }
            return r;
        }
        /// <summary>
        /// 删除指定缓存类型
        /// </summary>
        /// <param name="xapname"></param>
        /// <param name="typename"></param>
        public void RemovePage(string xapname, string typename) {
            var x = from item in pages where item[xapname] != null && item[xapname][typename] != null select item;
            if (x.Count() == 1) {
                pages.Remove(x.First());
            }
        }
        /// <summary>
        /// 获取管理缓存中的实例
        /// </summary>
        /// <param name="xapname"></param>
        /// <param name="typename"></param>
        /// <returns></returns>
        public object GetView(string xapname, string typename) {
            var r = default(object);
            var x = from item in pages where item[xapname] != null && item[xapname][typename] != null select item;
            if (x.Count() == 1) {
                r = x.First().Item1;
            }
            return r;
        }
        internal Dictionary<string, Assembly> bags;
        //[ThreadStatic]
        //volatile byte[] dllBuffer;
        //System.Threading.AutoResetEvent are;
        //static int mark;
        object lockmark = new object();
        void CheckBag(string id) {
            var x = new BagException(id);
            this.bagExceptionStore.Add(x);
            throw x;
        }
        internal void LoadMudel(string xap, string typename) {
            if (bags[xap] == null) {//只要相关xap的assembly为空就会抛异常
                //Interlocked.Exchange(ref mark, 0);
                var id = string.Format("{0}.{1}", xap, typename);
                Ex.LoadAssemblyByXap(xap, xap, x => {//通常一个xap包中只有一个用户程序集其它为系统程序集
                    bags[xap] = x;
                    var xapbags = this.bagExceptionStore.Where(y => y.id == id);
                    var x2 = xapbags.First();
                    x2.Invoke();
                    this.bagExceptionStore.Remove(x2);
                    //Interlocked.Exchange(ref mark, 1);
                });
                CheckBag(id);
            }
        }
        [ThreadStatic]
        internal volatile List<BagException> bagExceptionStore;
    }
}
